#include "hierarchicalwritter.hpp"

namespace yxml
{
    HierarchicalWritterDeprecated::HierarchicalWritterDeprecated( ostream& out ):Writter( out )
    {
    }

    void HierarchicalWritterDeprecated::write( Document& document )
    {
        _out << "<?xml version=\"1.0\" standalone=\"yes\" encoding=\"" << document.encoding() << "\" ?>" << endl;
        _level = 0;
        writeNode( document );
    }

    void HierarchicalWritterDeprecated::writeNode( Node& node )
    {
        for( int i=0; i < _level; ++i ) putChar( ' ' );
        string value = node.value();
        map<string, string> &attributes = node.attributes();
        switch( node.type() )
        {
        case TAG:
            _out << "<"<<value;
            for( map<string, string>::iterator it = attributes.begin(); it != attributes.end(); ++it )
            {
                _out << " " << it->first << " = \"" << it->second << "\"";
            }
            if( node.count() )
            {
                _out << ">" << endl;
                _level += 2;
                for( Node* kid = &node.firstChild(); kid->type() != NONE ; kid = &kid->nextBrother() )
                    writeNode( *kid );
                _level -= 2;
                for( int i=0; i < _level; ++i ) putChar( ' ' );
                _out << "</" << value << ">" << endl;
            }
            else _out << "/>" << endl;
            break;
        case TEXT:
            for( size_t i=0; i < value.size(); ++i )
            {
                putChar( value[i] );
                if( value[i]=='\n' )
                    for( int j=0; j < _level; ++j ) putChar( ' ' );
            }
            _out << endl;
            break;
        case COMMENT:
            _out << "<!--";
            for( size_t i=0; i < value.size(); ++i )
            {
                putChar( value[i] );
                if( value[i]=='\n' )
                    for( int j=0; j < _level+4; ++j ) putChar( ' ' );
            }
            _out << "-->" <<endl;
            break;
        default:
            break;
        }
    }

    HierarchicalWritter::HierarchicalWritter( ostream& out ): LineSeparatedWritter( out )
    {
        _identationLevel = 0;
        _identationIncrement = 2;
    }

    void HierarchicalWritter::writeNode( Node& node )
    {
        _out << getIdentation();
        LineSeparatedWritter::writeNode( node );
    }

    void HierarchicalWritter::writeComment( Node& node )
    {
        _identationLevel += 5;
        LineSeparatedWritter::writeComment( node );
        _identationLevel -= 5;
    }

    string HierarchicalWritter::fixText( string s )
    {
        s = LineSeparatedWritter::fixText( s );
        //Replace all \s to \\s
        size_t pos = 0;
        while( ( pos=s.find( '\n', pos ) ) != string::npos )
        {
            s.insert( pos+1, getIdentation() );
            pos+= 5;
        }
        return s;
    }

    void HierarchicalWritter::writeSubNodes( Node& node )
    {
        _identationLevel += _identationIncrement;
        LineSeparatedWritter::writeSubNodes(node);
        _identationLevel -= _identationIncrement;
        _out << getIdentation();
    }

}
